//using System;
//using System.Linq;
//using Microsoft.CodeAnalysis;
//using Microsoft.CodeAnalysis.CSharp;
//using Microsoft.CodeAnalysis.CSharp.Syntax;
//using Microsoft.CodeAnalysis.Text;

//namespace UIOC.CodeAnalysis.Generators;

//[Generator]
//public sealed class AutoImplementGenerator : IIncrementalGenerator {
//    public void Initialize(IncrementalGeneratorInitializationContext incrementalGeneratorInitializationContext) {
//        var autoImplementInterfaceDeclarationSyntaxList = incrementalGeneratorInitializationContext.SyntaxProvider
//            .CreateSyntaxProvider(
//                predicate: static (syntaxNode, _) => syntaxNode is InterfaceDeclarationSyntax interfaceDeclarationSyntax && HasAutoImplementAttribute(interfaceDeclarationSyntax),
//                transform: static (syntaxContext, _) => (InterfaceDeclarationSyntax)syntaxContext.Node
//            )
//            .Collect();

//        incrementalGeneratorInitializationContext.RegisterSourceOutput(autoImplementInterfaceDeclarationSyntaxList, (sourceProductionContext, interfaceDeclarationSyntaxCollection) => {
//            foreach (var interfaceDeclarationSyntax in interfaceDeclarationSyntaxCollection) {
//                var namespaceName = GetNamespace(interfaceDeclarationSyntax);
//                var interfaceTypeName = interfaceDeclarationSyntax.Identifier.Text;
//                var implementationTypeName = interfaceTypeName + "Impl";

//                var compilationUnitSyntax = GenerateImplementation(namespaceName, interfaceTypeName, implementationTypeName, interfaceDeclarationSyntax);
//                var sourceText = SourceText.From(compilationUnitSyntax.NormalizeWhitespace().ToFullString(), System.Text.Encoding.UTF8);
//                sourceProductionContext.AddSource($"{implementationTypeName}.g.cs", sourceText);
//            }
//        });
//    }

//    private static bool HasAutoImplementAttribute(InterfaceDeclarationSyntax interfaceDeclarationSyntax) {
//        return interfaceDeclarationSyntax.AttributeLists
//            .SelectMany(attributeListSyntax => attributeListSyntax.Attributes)
//            .Any(attributeSyntax => attributeSyntax.Name.ToString().Contains("AutoImplement"));
//    }

//    private static string GetNamespace(InterfaceDeclarationSyntax interfaceDeclarationSyntax) {
//        SyntaxNode? parentSyntaxNode = interfaceDeclarationSyntax.Parent;
//        while (parentSyntaxNode != null && parentSyntaxNode is not NamespaceDeclarationSyntax && parentSyntaxNode is not FileScopedNamespaceDeclarationSyntax)
//            parentSyntaxNode = parentSyntaxNode.Parent;
//        return parentSyntaxNode switch {
//            NamespaceDeclarationSyntax namespaceDeclarationSyntax => namespaceDeclarationSyntax.Name.ToString(),
//            FileScopedNamespaceDeclarationSyntax fileScopedNamespaceDeclarationSyntax => fileScopedNamespaceDeclarationSyntax.Name.ToString(),
//            _ => "Generated"
//        };
//    }

//    private static CompilationUnitSyntax GenerateImplementation(string namespaceName, string interfaceTypeName, string implementationTypeName, InterfaceDeclarationSyntax interfaceDeclarationSyntax) {
//        var memberDeclarationSyntaxList = interfaceDeclarationSyntax.Members.Select(memberSyntax => {
//            switch (memberSyntax) {
//                case MethodDeclarationSyntax methodDeclarationSyntax:
//                    var methodDeclaration = SyntaxFactory.MethodDeclaration(
//                        methodDeclarationSyntax.ReturnType,
//                        methodDeclarationSyntax.Identifier
//                    )
//                    .WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword)))
//                    .WithParameterList(methodDeclarationSyntax.ParameterList)
//                    .WithBody(
//                        SyntaxFactory.Block(
//                            methodDeclarationSyntax.ReturnType.ToString() == "void"
//                                ? Array.Empty<StatementSyntax>()
//                                : new[] { SyntaxFactory.ReturnStatement(SyntaxFactory.DefaultExpression(methodDeclarationSyntax.ReturnType)) }
//                        )
//                    );
//                    return (MemberDeclarationSyntax)methodDeclaration;

//                case PropertyDeclarationSyntax propertyDeclarationSyntax:
//                    var propertyDeclaration = SyntaxFactory.PropertyDeclaration(
//                        propertyDeclarationSyntax.Type,
//                        propertyDeclarationSyntax.Identifier
//                    )
//                    .WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword)))
//                    .WithAccessorList(
//                        SyntaxFactory.AccessorList(
//                            SyntaxFactory.List(new[]
//                            {
//                                SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
//                                    .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)),
//                                SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
//                                    .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
//                            })
//                        )
//                    );
//                    return (MemberDeclarationSyntax)propertyDeclaration;

//                default:
//                    return null;
//            }
//        })
//        .Where(memberDeclarationSyntax => memberDeclarationSyntax != null)
//        .ToList();

//        var classDeclarationSyntax = SyntaxFactory.ClassDeclaration(implementationTypeName)
//            .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.SealedKeyword))
//            .AddBaseListTypes(SyntaxFactory.SimpleBaseType(SyntaxFactory.IdentifierName(interfaceTypeName)))
//            .AddMembers(memberDeclarationSyntaxList.ToArray());

//        var namespaceDeclarationSyntax = SyntaxFactory.NamespaceDeclaration(SyntaxFactory.ParseName(namespaceName))
//            .AddMembers(classDeclarationSyntax);

//        var compilationUnitSyntax = SyntaxFactory.CompilationUnit()
//            .AddUsings(SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName("System")))
//            .AddMembers(namespaceDeclarationSyntax);

//        return compilationUnitSyntax;
//    }
//}
